package com.java2nb.novel.pay.common;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 签名工具类（遵循文档MD5签名算法）
 */
@Slf4j
public class SignUtils {
    private static final String SIGN_TYPE_MD5 = "MD5";

    /**
     * 生成签名
     * @param params 待签名参数（Map）
     * @param secretKey 私钥
     * @return 签名结果（大写）
     */
    public static String generateSign(Map<String, Object> params, String secretKey) {
        // 1. 过滤空值参数，排除sign字段
        Map<String, Object> filteredParams = new HashMap<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value != null && !"".equals(value.toString()) && !"sign".equals(key)) {
                filteredParams.put(key, value);
            }
        }

        // 2. 按参数名不区分大小写自然排序（TreeMap按key自然排序）
        Map<String, Object> sortedParams = new TreeMap<>((k1, k2) -> k1.compareTo(k2));
        sortedParams.putAll(filteredParams);

        // 3. 拼接成key=value&格式
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : sortedParams.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }

        // 4. 拼接私钥（&key=secretKey）
        sb.append("key=").append(secretKey);
        log.info("待签名参数：{}", sb.toString());
        // 5. MD5加密并转大写
        return  DigestUtils.md5Hex(sb.toString()).toUpperCase();

    }

    /**
     * 验证签名
     * @param params 待验证参数（Map）
     * @param secretKey 私钥
     * @param sign 待验证签名
     * @return true=签名正确，false=签名错误
     */
    public static boolean verifySign(Map<String, Object> params, String secretKey, String sign) {
        if (sign == null || sign.isEmpty()) {
            return false;
        }
        String generatedSign = generateSign(params, secretKey);
        return generatedSign.equals(sign);
    }

    /**
     * 将JSON对象转为Map（用于签名验证）
     * @param jsonObject JSON对象
     * @return Map
     */
    public static Map<String, Object> jsonToMap(JSONObject jsonObject) {
        Map<String, Object> map = new HashMap<>();
        for (String key : jsonObject.keySet()) {
            map.put(key, jsonObject.get(key));
        }
        return map;
    }
}